﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;

namespace Luka.Log;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class LoggingAttribute : Attribute, IAsyncActionFilter
{
    /// <summary>
    /// 是否仅记录异常
    /// </summary>
    public bool OnlyE { get; set; } = false;

    /// <summary>
    /// 描述
    /// </summary>
    public string Desc { get; set; }

    /// <summary>
    /// 异步方法，用于在执行操作之前执行一些操作
    /// </summary>
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // 如果内部应用程序的日志选项未启用
        if (!InternalApp.LogOptions.Enabled)
        {
            // 等待下一个操作
            await next();
        }
        else
        {
            try
            {
                // 调用next()方法，获取数据
                var data = await next();
                // 创建LogModel对象
                var model = new LoggingModel();
                // 如果InternalApp.UserInfo不为空，则将InternalApp.UserInfo赋值给model.UserInfo，否则将空字符串赋值给model.UserInfo
                model.UserInfo = !string.IsNullOrEmpty(InternalApp.UserInfo) ? InternalApp.UserInfo : default;
                // 获取HttpContext中的Request对象
                var request = context.HttpContext.Request;
                // 设置LogModel对象的Path属性
                model.Path = request.Path;
                // 设置LogModel对象的Method属性
                model.Method = request.Method;
                // 设置LogModel对象的Desc属性
                model.Desc = Desc;
                // 调用request.GetParams()方法，获取Query、Form、Body参数
                (string Query, string Form, string Body) = await request.GetParams();
                // 设置LogModel对象的Form属性
                model.Form = Form;
                // 设置LogModel对象的Body属性
                model.Body = Body;
                // 设置LogModel对象的Query属性
                model.Query = Query;
                // 判断data中是否有异常
                if (data.Exception != null)
                {
                    // 设置LogModel对象的Error属性
                    model.Error = data.Exception.Message;
                    // 设置LogModel对象的StackTrace属性
                    model.StackTrace = data.Exception?.StackTrace;
                    // 记录错误日志
                    Logging.Error(model);
                }
                // 判断data中是否有结果，并且OnlyE为false
                else if (data.Result != null && !OnlyE)
                {
                    // 根据data.Result的类型，获取value
                    var value = data.Result switch
                    {
                        ContentResult content => content.Content,
                        ObjectResult obj => obj.Value,
                        JsonResult json => json.Value,
                        _ => null,
                    };
                    // 判断value是否为null
                    if (value != null)
                        // 将value序列化为Json字符串，并设置LogModel对象的Result属性
                        model.Result = JsonConvert.SerializeObject(value);
                    // 记录结果日志
                    Logging.Info(model);
                }
            }
            catch (Exception)
            {
                // 抛出异常
                throw;
            }
        }
    }
}